# 面向对象的学生信息管理系统

class Student:
    """学生类，用于表示学生实体"""
    
    def __init__(self, student_id, name, age, gender, score):
        self.student_id = student_id
        self.name = name
        self.age = age
        self.gender = gender
        self.score = score
    
    def __str__(self):
        """返回学生信息的字符串表示"""
        return f"{self.student_id}\t{self.name}\t{self.age}\t{self.gender}\t{self.score}"
    
    def to_dict(self):
        """将学生对象转换为字典"""
        return {
            "student_id": self.student_id,
            "name": self.name,
            "age": self.age,
            "gender": self.gender,
            "score": self.score
        }
    
    @classmethod
    def from_dict(cls, data):
        """从字典创建学生对象"""
        return cls(
            data["student_id"],
            data["name"],
            data["age"],
            data["gender"],
            data["score"]
        )


class StudentManager:
    """学生管理类，负责学生信息的增删改查"""
    
    def __init__(self):
        self.students = []
    
    def add_student(self, student):
        """添加学生"""
        # 检查学号是否已存在
        for s in self.students:
            if s.student_id == student.student_id:
                return False, "学号已存在"
        self.students.append(student)
        return True, "学生添加成功"
    
    def get_all_students(self):
        """获取所有学生"""
        return self.students
    
    def search_by_id(self, student_id):
        """按学号查询学生"""
        for student in self.students:
            if student.student_id == student_id:
                return student
        return None
    
    def search_by_name(self, name):
        """按姓名查询学生"""
        result = []
        for student in self.students:
            if name.lower() in student.name.lower():
                result.append(student)
        return result
    
    def update_student(self, student_id, new_data):
        """更新学生信息"""
        student = self.search_by_id(student_id)
        if not student:
            return False, "学生不存在"
        
        # 更新学生信息
        if "name" in new_data:
            student.name = new_data["name"]
        if "age" in new_data:
            student.age = new_data["age"]
        if "gender" in new_data:
            student.gender = new_data["gender"]
        if "score" in new_data:
            student.score = new_data["score"]
        
        return True, "学生信息更新成功"
    
    def delete_student(self, student_id):
        """删除学生"""
        student = self.search_by_id(student_id)
        if not student:
            return False, "学生不存在"
        
        self.students.remove(student)
        return True, "学生删除成功"
    
    def get_statistics(self):
        """获取统计信息"""
        if not self.students:
            return {
                "count": 0,
                "average_score": 0,
                "max_score": 0,
                "min_score": 0
            }
        
        total_score = sum(student.score for student in self.students)
        max_score = max(student.score for student in self.students)
        min_score = min(student.score for student in self.students)
        
        return {
            "count": len(self.students),
            "average_score": total_score / len(self.students),
            "max_score": max_score,
            "min_score": min_score
        }


class FileHandler:
    """文件处理类，负责数据的保存和读取"""
    
    def __init__(self, filename="students.txt"):
        self.filename = filename
    
    def save_data(self, students):
        """保存学生数据到文件"""
        try:
            with open(self.filename, "w", encoding="utf-8") as file:
                for student in students:
                    file.write(f"{student.student_id},{student.name},{student.age},{student.gender},{student.score}\n")
            return True, "数据保存成功"
        except Exception as e:
            return False, f"数据保存失败: {str(e)}"
    
    def load_data(self):
        """从文件加载学生数据"""
        students = []
        try:
            with open(self.filename, "r", encoding="utf-8") as file:
                for line in file:
                    data = line.strip().split(",")
                    if len(data) == 5:
                        student = Student(
                            data[0],
                            data[1],
                            int(data[2]),
                            data[3],
                            float(data[4])
                        )
                        students.append(student)
            return True, students, "数据加载成功"
        except FileNotFoundError:
            return True, [], "数据文件不存在，将创建新文件"
        except Exception as e:
            return False, [], f"数据加载失败: {str(e)}"


class MainApp:
    """主应用类，处理用户交互"""
    
    def __init__(self):
        self.manager = StudentManager()
        self.file_handler = FileHandler()
        self.load_data()
    
    def load_data(self):
        """加载数据"""
        success, students, message = self.file_handler.load_data()
        print(message)
        if success:
            for student in students:
                self.manager.add_student(student)
    
    def save_data(self):
        """保存数据"""
        students = self.manager.get_all_students()
        success, message = self.file_handler.save_data(students)
        print(message)
    
    def display_menu(self):
        """显示菜单"""
        print("\n===== 学生信息管理系统 =====")
        print("1. 添加学生信息")
        print("2. 显示所有学生信息")
        print("3. 按学号查询学生")
        print("4. 按姓名查询学生")
        print("5. 修改学生信息")
        print("6. 删除学生信息")
        print("7. 查看统计信息")
        print("8. 保存数据")
        print("9. 加载数据")
        print("0. 退出系统")
        print("==========================")
    
    def add_student(self):
        """添加学生信息"""
        print("\n--- 添加学生信息 ---")
        student_id = input("请输入学号: ")
        name = input("请输入姓名: ")
        
        # 验证年龄输入
        while True:
            try:
                age = int(input("请输入年龄: "))
                if age < 0 or age > 100:
                    print("年龄必须在0-100之间，请重新输入")
                    continue
                break
            except ValueError:
                print("年龄必须是数字，请重新输入")
        
        gender = input("请输入性别: ")
        
        # 验证成绩输入
        while True:
            try:
                score = float(input("请输入成绩: "))
                if score < 0 or score > 100:
                    print("成绩必须在0-100之间，请重新输入")
                    continue
                break
            except ValueError:
                print("成绩必须是数字，请重新输入")
        
        student = Student(student_id, name, age, gender, score)
        success, message = self.manager.add_student(student)
        print(message)
    
    def show_all_students(self):
        """显示所有学生信息"""
        print("\n--- 所有学生信息 ---")
        students = self.manager.get_all_students()
        if not students:
            print("暂无学生信息")
            return
        
        print("学号\t姓名\t年龄\t性别\t成绩")
        print("-" * 40)
        for student in students:
            print(student)
    
    def search_by_id(self):
        """按学号查询学生"""
        print("\n--- 按学号查询 ---")
        student_id = input("请输入要查询的学号: ")
        student = self.manager.search_by_id(student_id)
        
        if student:
            print("\n找到学生信息:")
            print(f"学号: {student.student_id}")
            print(f"姓名: {student.name}")
            print(f"年龄: {student.age}")
            print(f"性别: {student.gender}")
            print(f"成绩: {student.score}")
        else:
            print("未找到该学生信息")
    
    def search_by_name(self):
        """按姓名查询学生"""
        print("\n--- 按姓名查询 ---")
        name = input("请输入要查询的姓名: ")
        students = self.manager.search_by_name(name)
        
        if students:
            print(f"\n找到 {len(students)} 位学生:")
            print("学号\t姓名\t年龄\t性别\t成绩")
            print("-" * 40)
            for student in students:
                print(student)
        else:
            print("未找到相关学生信息")
    
    def update_student(self):
        """修改学生信息"""
        print("\n--- 修改学生信息 ---")
        student_id = input("请输入要修改的学生学号: ")
        student = self.manager.search_by_id(student_id)
        
        if not student:
            print("未找到该学生信息")
            return
        
        print(f"\n当前学生信息:")
        print(f"姓名: {student.name}")
        print(f"年龄: {student.age}")
        print(f"性别: {student.gender}")
        print(f"成绩: {student.score}")
        
        print("\n请输入新的信息(不修改的项目直接回车):")
        name = input(f"姓名({student.name}): ")
        age = input(f"年龄({student.age}): ")
        gender = input(f"性别({student.gender}): ")
        score = input(f"成绩({student.score}): ")
        
        new_data = {}
        if name:
            new_data["name"] = name
        if age:
            try:
                new_age = int(age)
                if new_age < 0 or new_age > 100:
                    print("年龄必须在0-100之间，已忽略")
                else:
                    new_data["age"] = new_age
            except ValueError:
                print("年龄必须是数字，已忽略")
        if gender:
            new_data["gender"] = gender
        if score:
            try:
                new_score = float(score)
                if new_score < 0 or new_score > 100:
                    print("成绩必须在0-100之间，已忽略")
                else:
                    new_data["score"] = new_score
            except ValueError:
                print("成绩必须是数字，已忽略")
        
        if new_data:
            success, message = self.manager.update_student(student_id, new_data)
            print(message)
        else:
            print("没有修改任何信息")
    
    def delete_student(self):
        """删除学生信息"""
        print("\n--- 删除学生信息 ---")
        student_id = input("请输入要删除的学生学号: ")
        
        confirm = input(f"确定要删除学号为 {student_id} 的学生吗？(y/n): ")
        if confirm.lower() != 'y':
            print("已取消删除操作")
            return
        
        success, message = self.manager.delete_student(student_id)
        print(message)
    
    def show_statistics(self):
        """显示统计信息"""
        print("\n--- 统计信息 ---")
        stats = self.manager.get_statistics()
        
        print(f"学生总数: {stats['count']}")
        print(f"平均成绩: {stats['average_score']:.2f}")
        print(f"最高成绩: {stats['max_score']}")
        print(f"最低成绩: {stats['min_score']}")
    
    def run(self):
        """运行主程序"""
        print("欢迎使用学生信息管理系统!")
        
        while True:
            self.display_menu()
            choice = input("请输入您的选择: ")
            
            if choice == "1":
                self.add_student()
            elif choice == "2":
                self.show_all_students()
            elif choice == "3":
                self.search_by_id()
            elif choice == "4":
                self.search_by_name()
            elif choice == "5":
                self.update_student()
            elif choice == "6":
                self.delete_student()
            elif choice == "7":
                self.show_statistics()
            elif choice == "8":
                self.save_data()
            elif choice == "9":
                self.load_data()
            elif choice == "0":
                confirm = input("确定要退出系统吗？(y/n): ")
                if confirm.lower() == 'y':
                    self.save_data()
                    print("感谢使用学生信息管理系统，再见!")
                    break
            else:
                print("无效的选择，请重新输入!")


# 程序入口
if __name__ == "__main__":
    app = MainApp()
    app.run()
